package server

import (
	. "gitee.com/youbeiwuhuan/go-xxljob-executor/biz/model"
	"gitee.com/youbeiwuhuan/go-xxljob-executor/enums/gluetype"
	. "gitee.com/youbeiwuhuan/go-xxljob-executor/global"
	"gitee.com/youbeiwuhuan/go-xxljob-executor/proccess"
	"gitee.com/youbeiwuhuan/go-xxljob-executor/run"
	"gitee.com/youbeiwuhuan/go-xxljob-executor/tools"
	"time"
)

const (
	SERIAL_EXECUTION = "SERIAL_EXECUTION"
	DISCARD_LATER    = "DISCARD_LATER"
	COVER_EARLY      = "COVER_EARLY"
)

type ExecutorBizImpl struct {
	triggerCallback *proccess.TriggerCallbackProccessor
}

func NewExecutorBizImpl(triggerCallback *proccess.TriggerCallbackProccessor) *ExecutorBizImpl {
	return &ExecutorBizImpl{
		triggerCallback: triggerCallback,
	}
}

func (t *ExecutorBizImpl) Beat() ReturnT {
	return ReturnT{Code: SUCCESS_CODE}
}

func (t *ExecutorBizImpl) IdleBeat(idleBeatParam IdleBeatParam) ReturnT {

	jobRunner := run.GetJubRunner(idleBeatParam.JobId)
	if nil != jobRunner && jobRunner.IsRunningOrHasQueue() {
		return ReturnT{
			Code: FAIL_CODE,
			Msg:  "job thread is running or has trigger queue.",
		}
	}

	return ReturnT{Code: SUCCESS_CODE}
}

func (t *ExecutorBizImpl) Run(triggerParam TriggerParam) ReturnT {
	Logger.Info("-----------------" + triggerParam.String())
	if triggerParam.GlueType != gluetype.BEAN {
		return ReturnT{
			Code: FAIL_CODE,
			Msg:  "only  support  one  GlueType:BEAN  !!! ",
		}
	}

	handler := run.GetJobHandler(triggerParam.ExecutorHandler)
	if nil == handler {
		return ReturnT{
			Code: FAIL_CODE,
			Msg:  "has no such ExecutorHandler!!",
		}
	}

	jobRunner := run.GetJubRunner(triggerParam.JobId)
	if nil == jobRunner {
		jobRunner = run.AddJobRunner(triggerParam.JobId, run.GetJobHandler(triggerParam.ExecutorHandler), t.triggerCallback)
	}

	switch triggerParam.ExecutorBlockStrategy {
	case SERIAL_EXECUTION:
		jobRunner.PushTriggerQueue(triggerParam)
	case DISCARD_LATER:
		if jobRunner.IsRunningOrHasQueue() {
			return ReturnT{Code: FAIL_CODE, Msg: "block strategy effect：" + DISCARD_LATER}
		} else {
			jobRunner.PushTriggerQueue(triggerParam)
		}
	case COVER_EARLY:
		jobRunner.Run(triggerParam)
	}

	return ReturnT{Code: SUCCESS_CODE}
}

func (t *ExecutorBizImpl) Kill(killParam KillParam) ReturnT {
	jobRunner := run.GetJubRunner(killParam.JobId)
	if nil == jobRunner {
		run.RemoveJobRunner(killParam.JobId)
		return ReturnT{
			Code: SUCCESS_CODE,
			Msg:  "scheduling center kill job.",
		}
	}

	return ReturnT{
		Code: SUCCESS_CODE,
		Msg:  "job thread already killed.",
	}
}

func (t *ExecutorBizImpl) Log(logParam LogParam) ReturnT {

	logFileName := tools.MakeLogFileName(logParam.LogId, time.Unix(logParam.LogDateTim/1000, 0))

	logResult := tools.ReadLog(logFileName, logParam.FromLineNum)
	return ReturnT{
		Code:    SUCCESS_CODE,
		Content: logResult,
	}
}
